package com.atguigu.gmall.activity.controller;

import com.atguigu.gmall.activity.redis.CacheHelper;
import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.activity.util.DateUtil;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.common.util.MD5;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/api/activity/seckill")
public class SeckillApiController {

    @Autowired
    private SeckillGoodsService seckillGoodsService;
    @Autowired
    private RabbitService rabbitService;
    @Autowired
    private RedisTemplate redisTemplate;

    //获取秒杀频道首页数据集合
    @GetMapping("/list")
    public List<SeckillGoods> list() {
        return seckillGoodsService.list();
    }

    //获取秒杀商品详情 秒杀的详情页
    @GetMapping("/item/{skuId}")
    public SeckillGoods item(@PathVariable String skuId) {
        return seckillGoodsService.item(skuId);
    }

    //获取抢购码/下单码
    @GetMapping("/auth/getSeckillSkuIdStr/{skuId}")
    public Result getSeckillSkuIdStr(@PathVariable String skuId, HttpServletRequest request) {
        SeckillGoods seckillGoods = seckillGoodsService.item(skuId);
        //1.商品是否审核通过
        if (!"1".equals(seckillGoods.getStatus())) {
            return Result.fail().message("商品审核不通过! 不能秒杀");
        }
        //2.商品是否还有货
        if (seckillGoods.getStockCount() <= 0) {
            return Result.fail().message("商品已售完");
        }
        //3.此商品活动是否还在继续  开始时间 <= 当前时间 < 结束时间
        Calendar calendar = Calendar.getInstance();
        Date curDate = calendar.getTime();
        Date startTime = seckillGoods.getStartTime();
        Date endTime = seckillGoods.getEndTime();

        //具体内部算法查看工具类
        //结束时间<=当前时间 不能秒杀
        if (DateUtil.dateCompare(endTime, curDate)) {
            return Result.fail().message("此商品活动已结束,不可以秒杀");
        }
        //当前时间<开始时间
        if (!DateUtil.dateCompare(startTime, curDate)) {
            return Result.fail().message("此商品活动未开始,不可以秒杀");
        }
        //4.发放抢购码 防止跳墙
        String userId = AuthContextHolder.getUserId(request);
        String skuIdStr = MD5.encrypt(userId);
        return Result.ok(skuIdStr);
    }

    //开始抢购
    @PostMapping("/auth/seckillOrder/{skuId}")
    public Result seckillOrder(@PathVariable Long skuId, String skuIdStr, HttpServletRequest request) {
        //1.校验抢购码
        String userId = AuthContextHolder.getUserId(request);
        if (StringUtils.isEmpty(skuIdStr)) {//无抢购码->请求不合法
            return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
        }
        if (!skuIdStr.equals(MD5.encrypt(userId))) {
            return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
        }
        //2.校验状态位
        Object status = CacheHelper.get(skuId.toString());
        if (!"1".equals(status)) {//已售完
            return Result.build(null, ResultCodeEnum.SECKILL_FINISH);
        }
        //3.发消息
        //用户的id  商品的id
        UserRecode userRecode = new UserRecode();
        userRecode.setUserId(userId);
        userRecode.setSkuId(skuId);
        //必须通过MQ发送userId和skuId 秒杀微服务->MQ->秒杀微服务
        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_SECKILL_USER,
                MqConst.ROUTING_SECKILL_USER, userRecode);
        //4.返回200 ->前端自动调用查询抢购结果的方法 每三秒查询一次
        return Result.ok();
    }

    //轮询查询秒杀结果 三秒查询一次 可能是 抢购成功我的订单/抢购成功去下单/排队中/抢购失败
    @GetMapping("/auth/checkOrder/{skuId}")
    public Result checkOrder(@PathVariable Long skuId, HttpServletRequest request) {
        String userId = AuthContextHolder.getUserId(request);
        //1.用户是否已经下单
        //TODO 下单
        Object o = redisTemplate.opsForValue().get(RedisConst.SECKILL_ORDERS_USERS + userId + ":" + skuId);
        if (null != o) {
            return Result.build(null, ResultCodeEnum.SECKILL_ORDER_SUCCESS);//218 下单成功
        }
        //2.校验用户是否已经来过
        Object o1 = redisTemplate.opsForValue().get(RedisConst.SECKILL_USER + userId + ":" + skuId);
        if (null != o1) {
            //用户已经来过
            //3.校验是否有抢购资格
            Object o2 = redisTemplate.opsForValue().get(RedisConst.SECKILL_ORDERS + userId + ":" + skuId);
            if (null != o2) {
                return Result.build(null, ResultCodeEnum.SECKILL_SUCCESS);//215 抢单成功
            } else {
                return Result.build(null, ResultCodeEnum.SECKILL_FAIL);//216 抢单失败
            }
        } else {
            //用户没来过
            //4.校验状态位
            Object status = CacheHelper.get(skuId.toString());
            if (!"1".equals(status)) {
                return Result.build(null, ResultCodeEnum.SECKILL_FINISH);//213 已售完
            } else {
                return Result.build(null, ResultCodeEnum.SECKILL_RUN);//211 排队中
            }
        }
    }
}
